﻿<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>35_TestClick</title>
    <link href="css/common.css" rel="stylesheet" />
    <script src="js/gl-matrix.js"></script>
</head>
<body>
    <div>
        <h1>19</h1>

        <h2>Great Designs Come from Great Designers --- Not from Great Design Processes</h2>

        <p>
            The basic premise underlying the SEI's [Software
            Engineering Institute] work on software process maturity
            is that the quality of a software product is largely
            determined by the quality of the software development
            and maintenance processes used to build it.
        </p>

        Mark Paulk [1995], "The evolution of the SEI's capability maturity model for software"

        <p>
            ...[W]hile some may see them as the crazy ones, we see
            genius, because the ones who are crazy enough to think
            that they can change the world, are the ones who do.
        </p>

        Steve Jobs, Apple commercial (1997)

    </div>
    <canvas id="mycanvas" style="position: absolute; left: 0; top: 0; width: 50%; height:50%; "></canvas>
    <script id="shader-vs" type="x-shader/x-vertex">
        attribute vec4 aPosition;
        attribute vec4 aColor;
        uniform mat4 uModelMatrix;
        uniform mat4 uViewMatrix;
        uniform mat4 uProjMatrix;
        varying vec4 vColor;
        uniform bool uClicked;

        void main() {
        gl_Position = uProjMatrix *  uViewMatrix * uModelMatrix * aPosition;
        if(uClicked) {
        vColor = vec4(1.0, 0.0, 0.0, 1.0);
        } else {
        vColor = aColor;
        }
        }
    </script>
    <script id="shader-fs" type="x-shader/x-fragment">
        precision mediump float;

        varying vec4 vColor;

        void main() {
        gl_FragColor = vColor;
        }
    </script>
    <script>
        var canvas = document.getElementById('mycanvas');
        canvas.width = canvas.clientWidth;
        canvas.height = canvas.clientHeight;

        var gl = canvas.getContext('webgl');

        var vertexShader = gl.createShader(gl.VERTEX_SHADER);
        gl.shaderSource(vertexShader, document.getElementById('shader-vs').innerHTML);
        gl.compileShader(vertexShader);

        var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
        gl.shaderSource(fragmentShader, document.getElementById('shader-fs').innerHTML);
        gl.compileShader(fragmentShader);

        var shaderProgram = gl.createProgram();
        gl.attachShader(shaderProgram, vertexShader);
        gl.attachShader(shaderProgram, fragmentShader);
        gl.linkProgram(shaderProgram);
        gl.useProgram(shaderProgram);

        var aPosition = gl.getAttribLocation(shaderProgram, 'aPosition');
        var aColor = gl.getAttribLocation(shaderProgram, 'aColor');
        var uModelMatrix = gl.getUniformLocation(shaderProgram, 'uModelMatrix');
        var uViewMatrix = gl.getUniformLocation(shaderProgram, 'uViewMatrix');
        var uProjMatrix = gl.getUniformLocation(shaderProgram, 'uProjMatrix');
        var uClicked = gl.getUniformLocation(shaderProgram, 'uClicked');

        // 模型矩阵
        var model = mat4.create();
        mat4.rotateX(model, mat4.create(), 0);
        gl.uniformMatrix4fv(uModelMatrix, false, model);

        // 视图矩阵
        var view = mat4.create();
        mat4.lookAt(view, vec3.fromValues(3, 4, 5), vec3.fromValues(0, 0, 0, 0), vec3.fromValues(1, 0, 0));
        gl.uniformMatrix4fv(uViewMatrix, false, view);

        // 投影矩阵
        var proj = mat4.create();
        mat4.perspective(proj, Math.PI * 90 / 180, canvas.width / canvas.height, 0.1, 10000);
        gl.uniformMatrix4fv(uProjMatrix, false, proj);

        // 顶点位置矩阵
        var positionBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
             1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0,  // v0-v1-v2-v3 front
             1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0,  // v0-v3-v4-v5 right
             1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0,  // v0-v5-v6-v1 up
            -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0,  // v1-v6-v7-v2 left
            -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, 1.0,  // v7-v4-v3-v2 down
             1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0   // v4-v7-v6-v5 back
        ]), gl.STATIC_DRAW);

        gl.vertexAttribPointer(aPosition, 3, gl.FLOAT, false, 0, 0);
        gl.enableVertexAttribArray(aPosition);

        // 顶点颜色矩阵
        var colorBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
            0.4, 0.4, 1.0, 0.4, 0.4, 1.0, 0.4, 0.4, 1.0, 0.4, 0.4, 1.0,  // v0-v1-v2-v3 front(blue)
            0.4, 1.0, 0.4, 0.4, 1.0, 0.4, 0.4, 1.0, 0.4, 0.4, 1.0, 0.4,  // v0-v3-v4-v5 right(green)
            1.0, 0.4, 0.4, 1.0, 0.4, 0.4, 1.0, 0.4, 0.4, 1.0, 0.4, 0.4,  // v0-v5-v6-v1 up(red)
            1.0, 1.0, 0.4, 1.0, 1.0, 0.4, 1.0, 1.0, 0.4, 1.0, 1.0, 0.4,  // v1-v6-v7-v2 left
            1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,  // v7-v4-v3-v2 down
            0.4, 1.0, 1.0, 0.4, 1.0, 1.0, 0.4, 1.0, 1.0, 0.4, 1.0, 1.0   // v4-v7-v6-v5 back
        ]), gl.STATIC_DRAW);

        gl.vertexAttribPointer(aColor, 3, gl.FLOAT, false, 0, 0);
        gl.enableVertexAttribArray(aColor);

        // 索引矩阵
        var indexBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
        gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint8Array([
             0, 1, 2, 0, 2, 3,    // front
             4, 5, 6, 4, 6, 7,    // right
             8, 9, 10, 8, 10, 11,    // up
            12, 13, 14, 12, 14, 15,    // left
            16, 17, 18, 16, 18, 19,    // down
            20, 21, 22, 20, 22, 23     // back
        ]), gl.STATIC_DRAW);

        // 渲染
        gl.clearColor(0.0, 0.0, 0.0, 0.0);
        gl.enable(gl.DEPTH_TEST);

        var xAxisAngle = 0;
        var yAxisAngle = 0;

        var render = function () {
            xAxisAngle += Math.PI / 180;
            yAxisAngle += Math.PI / 180;

            mat4.rotateX(model, mat4.create(), xAxisAngle);
            mat4.rotateY(model, model, xAxisAngle);
            gl.uniformMatrix4fv(uModelMatrix, false, model);

            gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
            gl.drawElements(gl.TRIANGLES, 36, gl.UNSIGNED_BYTE, 0);
        }

        var tick = function () {
            requestAnimationFrame(tick);
            render();
        }
        tick();

        canvas.onclick = function (ev) {
            var x = ev.clientX;
            var y = ev.clientY;
            var rect = ev.target.getBoundingClientRect();
            if (x < rect.left || x > rect.right || y < rect.top || y > rect.bottom) {
                return;
            }
            var canvasX = x - rect.left;
            var canvasY = y - rect.top;

            // 判断是否选中物体
            var picked = false;
            gl.uniform1i(uClicked, 1);
            render();
            var pixels = new Uint8Array(4);
            gl.readPixels(canvasX, canvasY, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
            if (pixels[0] == 255) {
                picked = true;
            }
            gl.uniform1i(uClicked, 0);
            render();

            if (picked) {
                alert('你点击了正方体！');
            }
        }
    </script>
</body>
</html>
